package cn.metona.mq;

import cn.metona.mq.config.ConfigManager;
import cn.metona.mq.core.*;
import cn.metona.mq.consumer.MessageConsumer;
import cn.metona.mq.producer.MessageProducer;
import cn.metona.mq.security.AuthManager;
import cn.metona.mq.utils.MonitorUtils;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.logging.Logger;

/**
 * 消息队列工具包
 * 提供简单易用的API来操作消息队列
 */
public class MQToolkit {
    private static final Logger logger = Logger.getLogger(MQToolkit.class.getName());

    private static final QueueManager queueManager = QueueManager.getInstance();
    private static final ConfigManager configManager = ConfigManager.getInstance();
    private static final AuthManager authManager = AuthManager.getInstance();

    // 私有构造函数，防止实例化
    private MQToolkit() {}

    /**
     * 创建队列
     *
     * @param queueName 队列名称
     * @return 消息队列实例
     */
    public static MessageQueue createQueue(String queueName) {
        if (queueName == null || queueName.isEmpty()) {
            throw new IllegalArgumentException("Queue name cannot be null or empty");
        }
        return queueManager.createQueue(queueName);
    }

    /**
     * 创建队列（可选择是否启用持久化）
     *
     * @param queueName 队列名称
     * @param enablePersistence 是否启用持久化
     * @return 消息队列实例
     */
    public static MessageQueue createQueue(String queueName, boolean enablePersistence) {
        if (queueName == null || queueName.isEmpty()) {
            throw new IllegalArgumentException("Queue name cannot be null or empty");
        }
        return queueManager.createQueue(queueName, enablePersistence);
    }

    /**
     * 获取队列
     *
     * @param queueName 队列名称
     * @return 消息队列实例，如果不存在返回null
     */
    public static MessageQueue getQueue(String queueName) {
        if (queueName == null || queueName.isEmpty()) {
            return null;
        }
        return queueManager.getQueue(queueName);
    }

    /**
     * 发送消息
     *
     * @param queueName 队列名称
     * @param topic 消息主题
     * @param body 消息内容
     * @return 消息ID
     */
    public static String sendMessage(String queueName, String topic, String body) {
        if (queueName == null || queueName.isEmpty()) {
            throw new IllegalArgumentException("Queue name cannot be null or empty");
        }
        if (topic == null || topic.isEmpty()) {
            throw new IllegalArgumentException("Topic cannot be null or empty");
        }
        if (body == null) {
            throw new IllegalArgumentException("Body cannot be null");
        }

        MessageQueue queue = getOrCreateQueue(queueName);
        Message message = new Message(topic, body);
        queue.sendMessage(message);
        return message.messageId();
    }

    /**
     * 发送带优先级的消息
     *
     * @param queueName 队列名称
     * @param topic 消息主题
     * @param body 消息内容
     * @param priority 优先级（数值越大优先级越高）
     * @return 消息ID
     */
    public static String sendMessageWithPriority(String queueName, String topic,
                                                 String body, int priority) {
        if (queueName == null || queueName.isEmpty()) {
            throw new IllegalArgumentException("Queue name cannot be null or empty");
        }
        if (topic == null || topic.isEmpty()) {
            throw new IllegalArgumentException("Topic cannot be null or empty");
        }
        if (body == null) {
            throw new IllegalArgumentException("Body cannot be null");
        }

        MessageQueue queue = getOrCreateQueue(queueName);
        Message message = new Message(topic, body, priority);
        queue.sendMessage(message);
        return message.messageId();
    }

    /**
     * 发送延迟消息
     *
     * @param queueName 队列名称
     * @param topic 消息主题
     * @param body 消息内容
     * @param delayTime 延迟时间（毫秒）
     * @return 消息ID
     */
    public static String sendDelayMessage(String queueName, String topic,
                                          String body, long delayTime) {
        if (queueName == null || queueName.isEmpty()) {
            throw new IllegalArgumentException("Queue name cannot be null or empty");
        }
        if (topic == null || topic.isEmpty()) {
            throw new IllegalArgumentException("Topic cannot be null or empty");
        }
        if (body == null) {
            throw new IllegalArgumentException("Body cannot be null");
        }
        if (delayTime < 0) {
            throw new IllegalArgumentException("Delay time cannot be negative");
        }

        MessageQueue queue = getOrCreateQueue(queueName);
        Message message = new Message(topic, body, delayTime);
        queue.sendMessage(message);
        return message.messageId();
    }

    /**
     * 发送带过期时间的消息
     *
     * @param queueName 队列名称
     * @param topic 消息主题
     * @param body 消息内容
     * @param expireSeconds 过期时间（秒）
     * @return 消息ID
     */
    public static String sendMessageWithTTL(String queueName, String topic,
                                            String body, long expireSeconds) {
        if (queueName == null || queueName.isEmpty()) {
            throw new IllegalArgumentException("Queue name cannot be null or empty");
        }
        if (topic == null || topic.isEmpty()) {
            throw new IllegalArgumentException("Topic cannot be null or empty");
        }
        if (body == null) {
            throw new IllegalArgumentException("Body cannot be null");
        }
        if (expireSeconds <= 0) {
            throw new IllegalArgumentException("Expire seconds must be positive");
        }

        MessageQueue queue = getOrCreateQueue(queueName);
        Message message = new Message(topic, body);
        // 设置过期时间
        message = new Message(
                message.messageId(),
                message.topic(),
                message.body(),
                message.priority(),
                message.createTime(),
                message.createTime().plusSeconds(expireSeconds),
                message.headers(),
                message.tag(),
                message.delayTime()
        );
        queue.sendMessage(message);
        return message.messageId();
    }

    /**
     * 批量发送消息
     *
     * @param queueName 队列名称
     * @param messages 消息列表
     */
    public static void sendMessages(String queueName, List<Message> messages) {
        if (queueName == null || queueName.isEmpty()) {
            throw new IllegalArgumentException("Queue name cannot be null or empty");
        }
        if (messages == null) {
            throw new IllegalArgumentException("Messages list cannot be null");
        }

        MessageQueue queue = getOrCreateQueue(queueName);
        queue.sendMessages(messages);
    }

    /**
     * 创建生产者
     *
     * @param producerId 生产者ID
     * @param queueName 队列名称
     * @return 消息生产者实例
     */
    public static MessageProducer createProducer(String producerId, String queueName) {
        if (producerId == null || producerId.isEmpty()) {
            throw new IllegalArgumentException("Producer ID cannot be null or empty");
        }
        if (queueName == null || queueName.isEmpty()) {
            throw new IllegalArgumentException("Queue name cannot be null or empty");
        }

        MessageQueue queue = getOrCreateQueue(queueName);
        return new MessageProducer(producerId, queue);
    }

    /**
     * 创建消费者
     *
     * @param consumerId 消费者ID
     * @param queueName 队列名称
     * @param messageHandler 消息处理器
     * @return 消费者实例
     */
    public static MessageConsumer createConsumer(String consumerId, String queueName,
                                                 Consumer<Message> messageHandler) {
        if (consumerId == null || consumerId.isEmpty()) {
            throw new IllegalArgumentException("Consumer ID cannot be null or empty");
        }
        if (queueName == null || queueName.isEmpty()) {
            throw new IllegalArgumentException("Queue name cannot be null or empty");
        }
        if (messageHandler == null) {
            throw new IllegalArgumentException("Message handler cannot be null");
        }

        MessageQueue queue = getOrCreateQueue(queueName);
        return new MessageConsumer(consumerId, queue, messageHandler);
    }

    /**
     * 创建并发消费者
     *
     * @param consumerId 消费者ID
     * @param queueName 队列名称
     * @param messageHandler 消息处理器
     * @param concurrency 并发数
     * @return 消费者实例
     */
    public static MessageConsumer createConsumer(String consumerId, String queueName,
                                                 Consumer<Message> messageHandler,
                                                 int concurrency) {
        if (consumerId == null || consumerId.isEmpty()) {
            throw new IllegalArgumentException("Consumer ID cannot be null or empty");
        }
        if (queueName == null || queueName.isEmpty()) {
            throw new IllegalArgumentException("Queue name cannot be null or empty");
        }
        if (messageHandler == null) {
            throw new IllegalArgumentException("Message handler cannot be null");
        }
        if (concurrency <= 0) {
            throw new IllegalArgumentException("Concurrency must be positive");
        }

        MessageQueue queue = getOrCreateQueue(queueName);
        return new MessageConsumer(consumerId, queue, messageHandler, 1, concurrency, true);
    }

    /**
     * 创建批处理消费者
     *
     * @param consumerId 消费者ID
     * @param queueName 队列名称
     * @param messageHandler 消息处理器
     * @param batchSize 批处理大小
     * @return 消费者实例
     */
    public static MessageConsumer createBatchConsumer(String consumerId, String queueName,
                                                      Consumer<Message> messageHandler,
                                                      int batchSize) {
        if (consumerId == null || consumerId.isEmpty()) {
            throw new IllegalArgumentException("Consumer ID cannot be null or empty");
        }
        if (queueName == null || queueName.isEmpty()) {
            throw new IllegalArgumentException("Queue name cannot be null or empty");
        }
        if (messageHandler == null) {
            throw new IllegalArgumentException("Message handler cannot be null");
        }
        if (batchSize <= 0) {
            throw new IllegalArgumentException("Batch size must be positive");
        }

        MessageQueue queue = getOrCreateQueue(queueName);
        return new MessageConsumer(consumerId, queue, messageHandler, batchSize, 1, true);
    }

    /**
     * 获取队列大小
     *
     * @param queueName 队列名称
     * @return 队列中消息数量
     */
    public static long getQueueSize(String queueName) {
        if (queueName == null || queueName.isEmpty()) {
            return 0;
        }

        MessageQueue queue = queueManager.getQueue(queueName);
        return queue != null ? queue.size() : 0;
    }

    /**
     * 清空队列
     *
     * @param queueName 队列名称
     */
    public static void clearQueue(String queueName) {
        if (queueName == null || queueName.isEmpty()) {
            return;
        }

        MessageQueue queue = queueManager.getQueue(queueName);
        if (queue != null) {
            queue.clear();
        }
    }

    /**
     * 删除队列
     *
     * @param queueName 队列名称
     * @return 是否删除成功
     */
    public static boolean deleteQueue(String queueName) {
        if (queueName == null || queueName.isEmpty()) {
            return false;
        }

        return queueManager.deleteQueue(queueName);
    }

    /**
     * 获取队列统计信息
     *
     * @param queueName 队列名称
     * @return 队列统计信息
     */
    public static MessageQueue.QueueStats getQueueStats(String queueName) {
        if (queueName == null || queueName.isEmpty()) {
            return null;
        }

        MessageQueue queue = queueManager.getQueue(queueName);
        return queue != null ? queue.getStats() : null;
    }

    /**
     * 获取所有队列统计信息
     *
     * @return 所有队列统计信息数组
     */
    public static MessageQueue.QueueStats[] getAllQueueStats() {
        return queueManager.getAllQueueStats();
    }

    /**
     * 获取所有队列名称
     *
     * @return 队列名称数组
     */
    public static String[] getAllQueueNames() {
        return queueManager.getAllQueueNames();
    }

    /**
     * 启动队列
     *
     * @param queueName 队列名称
     */
    public static void startQueue(String queueName) {
        if (queueName == null || queueName.isEmpty()) {
            return;
        }

        MessageQueue queue = queueManager.getQueue(queueName);
        if (queue != null) {
            queue.start();
        }
    }

    /**
     * 停止队列
     *
     * @param queueName 队列名称
     */
    public static void stopQueue(String queueName) {
        if (queueName == null || queueName.isEmpty()) {
            return;
        }

        MessageQueue queue = queueManager.getQueue(queueName);
        if (queue != null) {
            queue.stop();
        }
    }

    /**
     * 暂停队列（同步原子操作）
     *
     * @param queueName 队列名称
     */
    public static void pauseQueue(String queueName) {
        if (queueName == null || queueName.isEmpty()) {
            return;
        }

        MessageQueue queue = queueManager.getQueue(queueName);
        if (queue != null) {
            queue.pause();
        }
    }

    /**
     * 恢复队列（同步原子操作）
     *
     * @param queueName 队列名称
     */
    public static void resumeQueue(String queueName) {
        if (queueName == null || queueName.isEmpty()) {
            return;
        }

        MessageQueue queue = queueManager.getQueue(queueName);
        if (queue != null) {
            queue.resume();
        }
    }

    /**
     * 暂停所有队列（同步原子操作）
     */
    public static void pauseAllQueues() {
        queueManager.pauseAllQueues();
    }

    /**
     * 恢复所有队列（同步原子操作）
     */
    public static void resumeAllQueues() {
        queueManager.resumeAllQueues();
    }

    /**
     * 启动所有队列
     */
    public static void startAllQueues() {
        queueManager.startAllQueues();
    }

    /**
     * 关闭所有队列
     */
    public static void shutdown() {
        queueManager.shutdown();
        logger.info("MQToolkit shutdown completed");
    }

    /**
     * 获取或创建队列
     */
    private static MessageQueue getOrCreateQueue(String queueName) {
        if (queueName == null || queueName.isEmpty()) {
            throw new IllegalArgumentException("Queue name cannot be null or empty");
        }

        MessageQueue queue = queueManager.getQueue(queueName);
        if (queue == null) {
            queue = queueManager.createQueue(queueName);
        }
        return queue;
    }

    /**
     * 获取配置管理器
     */
    public static ConfigManager getConfigManager() {
        return configManager;
    }

    /**
     * 获取认证管理器
     */
    public static AuthManager getAuthManager() {
        return authManager;
    }

    /**
     * 打印系统监控信息
     */
    public static void printMonitorInfo() {
        MonitorUtils.printAllQueueStats();
        MonitorUtils.printSystemHealth();
    }
}